Skip to main content

Java - Memory Visibility

Memory visibility trong Java là gì?

Memory visibility (khả năng nhìn thấy sự thay đổi của bộ nhớ) đề cập đến việc đảm bảo rằng các thay đổi (write) của một thread lên các biến chia sẻ (shared variables) sẽ được các thread khác thấy (read) một cách đúng đắn. Trong môi trường đa luồng, mỗi thread có thể có bản sao cục bộ của các biến trong bộ nhớ cache, vì vậy thay đổi ở một thread có thể không ngay lập tức được nhìn thấy bởi các thread khác. Java Memory Model (JMM) quy định cách mà các thread giao tiếp qua bộ nhớ chính và làm thế nào để đảm bảo tính nhất quán.

Ví dụ minh họa:

Xét trường hợp sử dụng biến volatile:

public class VisibilityExample {
// Khai báo biến flag là volatile để đảm bảo tính nhất quán giữa các thread
private volatile boolean flag = false;

// Phương thức của thread writer: đặt flag thành true
public void writer() {
flag = true;
}

// Phương thức của thread reader: chờ đến khi flag trở thành true
public void reader() {
while (!flag) {
// Chờ đợi flag được cập nhật thành true bởi thread khác
}
System.out.println("Flag đã được cập nhật thành true!");
}
}

Giải thích:

  • Ở ví dụ trên, biến flag được khai báo với từ khóa volatile. Điều này đảm bảo rằng khi thread writer thay đổi giá trị của flag thành true, sự thay đổi này sẽ được cập nhật ngay lập tức trong bộ nhớ chính và được nhìn thấy bởi thread reader.
  • Nếu không sử dụng volatile, thread reader có thể đang làm việc với bản sao cục bộ của flag và không nhận ra thay đổi được thực hiện bởi thread writer, dẫn đến vòng lặp vô hạn.
  • Từ khóa volatile giúp thiết lập mối quan hệ "happens-before" trong JMM, đảm bảo rằng các thao tác ghi và đọc lên biến được thực hiện theo thứ tự đúng.

Qua đó, memory visibility là một khía cạnh quan trọng trong lập trình đa luồng, giúp đảm bảo rằng các thread luôn làm việc với dữ liệu nhất quán.